{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 排序，搜索和计数\n",
    "## 排序\n",
    "### numpy.sort()\n",
    "- `numpy.sort(a[, axis=-1, kind='quicksort', order=None])` Return a sorted **copy** of an array.\n",
    "    - axis：排序沿数组的（轴）方向，0表示按行，1表示按列，None表示展开来排序，默认为-1，表示沿最后的轴排序。\n",
    "    - kind：排序的算法，提供了快排'quicksort'、混排'mergesort'、堆排'heapsort'， 默认为‘quicksort'。\n",
    "    - order：排序的字段名，可指定字段排序，默认为None。\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(20200612)\n",
    "x = np.random.rand(5, 5) * 10\n",
    "x = np.around(x, 2)\n",
    "print(x)\n",
    "# [[2.32 7.54 9.78 1.73 6.22]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [0.01 4.23 0.19 1.73 9.27]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [9.05 0.07 8.95 7.9  6.99]]\n",
    "\n",
    "y = np.sort(x)\n",
    "print(y)\n",
    "# [[1.73 2.32 6.22 7.54 9.78]\n",
    "#  [5.17 6.93 8.25 9.28 9.76]\n",
    "#  [0.01 0.19 1.73 4.23 9.27]\n",
    "#  [0.88 4.29 4.97 7.32 7.99]\n",
    "#  [0.07 6.99 7.9  8.95 9.05]]\n",
    "\n",
    "y = np.sort(x, axis=0)\n",
    "print(y)\n",
    "# [[0.01 0.07 0.19 1.73 4.29]\n",
    "#  [2.32 4.23 0.88 1.73 6.22]\n",
    "#  [6.93 4.97 8.95 7.32 6.99]\n",
    "#  [7.99 5.17 9.28 7.9  8.25]\n",
    "#  [9.05 7.54 9.78 9.76 9.27]]\n",
    "\n",
    "y = np.sort(x, axis=1)\n",
    "print(y)\n",
    "# [[1.73 2.32 6.22 7.54 9.78]\n",
    "#  [5.17 6.93 8.25 9.28 9.76]\n",
    "#  [0.01 0.19 1.73 4.23 9.27]\n",
    "#  [0.88 4.29 4.97 7.32 7.99]\n",
    "#  [0.07 6.99 7.9  8.95 9.05]]\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "dt = np.dtype([('name', 'S10'), ('age', np.int)])\n",
    "a = np.array([(\"Mike\", 21), (\"Nancy\", 25), (\"Bob\", 17), (\"Jane\", 27)], dtype=dt)\n",
    "b = np.sort(a, order='name')\n",
    "print(b)\n",
    "# [(b'Bob', 17) (b'Jane', 27) (b'Mike', 21) (b'Nancy', 25)]\n",
    "\n",
    "b = np.sort(a, order='age')\n",
    "print(b)\n",
    "# [(b'Bob', 17) (b'Mike', 21) (b'Nancy', 25) (b'Jane', 27)]\n",
    "```\n",
    "\n",
    "\n",
    "如果排序后，想用元素的索引位置替代排序后的实际结果，该怎么办呢？\n",
    "### numpy.argsort()\n",
    "- `numpy.argsort(a[, axis=-1, kind='quicksort', order=None])` Returns the indices that would sort an array.\n",
    "\n",
    "\n",
    "\n",
    "【例】对数组沿给定轴执行间接排序，并使用指定排序类型返回数据的索引数组。这个索引数组用于构造排序后的数组。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(20200612)\n",
    "x = np.random.randint(0, 10, 10)\n",
    "print(x)\n",
    "# [6 1 8 5 5 4 1 2 9 1]\n",
    "\n",
    "y = np.argsort(x)\n",
    "print(y)\n",
    "# [1 6 9 7 5 3 4 0 2 8]\n",
    "\n",
    "print(x[y])\n",
    "# [1 1 1 2 4 5 5 6 8 9]\n",
    "\n",
    "y = np.argsort(-x)\n",
    "print(y)\n",
    "# [8 2 0 3 4 5 7 1 6 9]\n",
    "\n",
    "print(x[y])\n",
    "# [9 8 6 5 5 4 2 1 1 1]\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(20200612)\n",
    "x = np.random.rand(5, 5) * 10\n",
    "x = np.around(x, 2)\n",
    "print(x)\n",
    "# [[2.32 7.54 9.78 1.73 6.22]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [0.01 4.23 0.19 1.73 9.27]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [9.05 0.07 8.95 7.9  6.99]]\n",
    "\n",
    "y = np.argsort(x)\n",
    "print(y)\n",
    "# [[3 0 4 1 2]\n",
    "#  [1 0 4 2 3]\n",
    "#  [0 2 3 1 4]\n",
    "#  [2 4 1 3 0]\n",
    "#  [1 4 3 2 0]]\n",
    "\n",
    "y = np.argsort(x, axis=0)\n",
    "print(y)\n",
    "# [[2 4 2 0 3]\n",
    "#  [0 2 3 2 0]\n",
    "#  [1 3 4 3 4]\n",
    "#  [3 1 1 4 1]\n",
    "#  [4 0 0 1 2]]\n",
    "\n",
    "y = np.argsort(x, axis=1)\n",
    "print(y)\n",
    "# [[3 0 4 1 2]\n",
    "#  [1 0 4 2 3]\n",
    "#  [0 2 3 1 4]\n",
    "#  [2 4 1 3 0]\n",
    "#  [1 4 3 2 0]]\n",
    "\n",
    "y = np.array([np.take(x[i], np.argsort(x[i])) for i in range(5)])  \n",
    "#numpy.take(a, indices, axis=None, out=None, mode='raise')沿轴从数组中获取元素。\n",
    "print(y)\n",
    "# [[1.73 2.32 6.22 7.54 9.78]\n",
    "#  [5.17 6.93 8.25 9.28 9.76]\n",
    "#  [0.01 0.19 1.73 4.23 9.27]\n",
    "#  [0.88 4.29 4.97 7.32 7.99]\n",
    "#  [0.07 6.99 7.9  8.95 9.05]]\n",
    "```\n",
    "\n",
    "如何将数据按照某一指标进行排序呢？\n",
    "### numpy.lexsort()\n",
    "- `numpy.lexsort(keys[, axis=-1])` Perform an indirect stable sort using a sequence of keys.（使用键序列执行间接稳定排序。）\n",
    "\n",
    "- 给定多个可以在电子表格中解释为列的排序键，lexsort返回一个整数索引数组，该数组描述了按多个列排序的顺序。序列中的最后一个键用于主排序顺序，倒数第二个键用于辅助排序顺序，依此类推。keys参数必须是可以转换为相同形状的数组的对象序列。如果为keys参数提供了2D数组，则将其行解释为排序键，并根据最后一行，倒数第二行等进行排序。\n",
    "\n",
    "\n",
    "\n",
    "【例】按照第一列的升序或者降序对整体数据进行排序。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(20200612)\n",
    "x = np.random.rand(5, 5) * 10\n",
    "x = np.around(x, 2)\n",
    "print(x)\n",
    "# [[2.32 7.54 9.78 1.73 6.22]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [0.01 4.23 0.19 1.73 9.27]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [9.05 0.07 8.95 7.9  6.99]]\n",
    "\n",
    "index = np.lexsort([x[:, 0]])\n",
    "print(index)\n",
    "# [2 0 1 3 4]\n",
    "\n",
    "y = x[index]\n",
    "print(y)\n",
    "# [[0.01 4.23 0.19 1.73 9.27]\n",
    "#  [2.32 7.54 9.78 1.73 6.22]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [9.05 0.07 8.95 7.9  6.99]]\n",
    "\n",
    "index = np.lexsort([-1 * x[:, 0]])\n",
    "print(index)\n",
    "# [4 3 1 0 2]\n",
    "\n",
    "y = x[index]\n",
    "print(y)\n",
    "# [[9.05 0.07 8.95 7.9  6.99]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [2.32 7.54 9.78 1.73 6.22]\n",
    "#  [0.01 4.23 0.19 1.73 9.27]]\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([1, 5, 1, 4, 3, 4, 4])\n",
    "y = np.array([9, 4, 0, 4, 0, 2, 1])\n",
    "a = np.lexsort([x])\n",
    "b = np.lexsort([y])\n",
    "print(a)\n",
    "# [0 2 4 3 5 6 1]\n",
    "print(x[a])\n",
    "# [1 1 3 4 4 4 5]\n",
    "\n",
    "print(b)\n",
    "# [2 4 6 5 1 3 0]\n",
    "print(y[b])\n",
    "# [0 0 1 2 4 4 9]\n",
    "\n",
    "z = np.lexsort([y, x])\n",
    "print(z)\n",
    "# [2 0 4 6 5 3 1]\n",
    "print(x[z])\n",
    "# [1 1 3 4 4 4 5]\n",
    "\n",
    "z = np.lexsort([x, y])\n",
    "print(z)\n",
    "# [2 4 6 5 3 1 0]\n",
    "print(y[z])\n",
    "# [0 0 1 2 4 4 9]\n",
    "```\n",
    "### numpy.partition()\n",
    "- `numpy.partition(a, kth, axis=-1, kind='introselect', order=None)` Return a partitioned copy of an array.\n",
    "\n",
    "Creates a copy of the array with its elements rearranged in such a way that the value of the element in k-th position is in the position it would be in a sorted array. All elements smaller than the k-th element are moved before this element and all equal or greater are moved behind it. The ordering of the elements in the two partitions is undefined.\n",
    "\n",
    "\n",
    "【例】以索引是 kth 的元素为基准，将元素分成两部分，即大于该元素的放在其后面，小于该元素的放在其前面，这里有点类似于快排。\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(100)\n",
    "x = np.random.randint(1, 30, [8, 3])\n",
    "print(x)\n",
    "# [[ 9 25  4]\n",
    "#  [ 8 24 16]\n",
    "#  [17 11 21]\n",
    "#  [ 3 22  3]\n",
    "#  [ 3 15  3]\n",
    "#  [18 17 25]\n",
    "#  [16  5 12]\n",
    "#  [29 27 17]]\n",
    "\n",
    "y = np.sort(x, axis=0)\n",
    "print(y)\n",
    "# [[ 3  5  3]\n",
    "#  [ 3 11  3]\n",
    "#  [ 8 15  4]\n",
    "#  [ 9 17 12]\n",
    "#  [16 22 16]\n",
    "#  [17 24 17]\n",
    "#  [18 25 21]\n",
    "#  [29 27 25]]\n",
    "\n",
    "z = np.partition(x, kth=2, axis=0)\n",
    "print(z)\n",
    "# [[ 3  5  3]\n",
    "#  [ 3 11  3]\n",
    "#  [ 8 15  4]\n",
    "#  [ 9 22 21]\n",
    "#  [17 24 16]\n",
    "#  [18 17 25]\n",
    "#  [16 25 12]\n",
    "#  [29 27 17]]\n",
    "```\n",
    "【例】选取每一列第三小的数\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(100)\n",
    "x = np.random.randint(1, 30, [8, 3])\n",
    "print(x)\n",
    "# [[ 9 25  4]\n",
    "#  [ 8 24 16]\n",
    "#  [17 11 21]\n",
    "#  [ 3 22  3]\n",
    "#  [ 3 15  3]\n",
    "#  [18 17 25]\n",
    "#  [16  5 12]\n",
    "#  [29 27 17]]\n",
    "z = np.partition(x, kth=2, axis=0)\n",
    "print(z[2])\n",
    "# [ 8 15  4]\n",
    "```\n",
    "\n",
    "【例】选取每一列第三大的数据\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(100)\n",
    "x = np.random.randint(1, 30, [8, 3])\n",
    "print(x)\n",
    "# [[ 9 25  4]\n",
    "#  [ 8 24 16]\n",
    "#  [17 11 21]\n",
    "#  [ 3 22  3]\n",
    "#  [ 3 15  3]\n",
    "#  [18 17 25]\n",
    "#  [16  5 12]\n",
    "#  [29 27 17]]\n",
    "z = np.partition(x, kth=-3, axis=0)\n",
    "print(z[-3])\n",
    "# [17 24 17]\n",
    "```\n",
    "### numpy.argpartition()\n",
    "\n",
    "- `numpy.argpartition(a, kth, axis=-1, kind='introselect', order=None)`\n",
    "\n",
    "Perform an indirect partition along the given axis using the algorithm specified by the `kind` keyword. It returns an array of indices of the same shape as `a` that index data along the given axis in partitioned order.\n",
    "\n",
    "【例】\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(100)\n",
    "x = np.random.randint(1, 30, [8, 3])\n",
    "print(x)\n",
    "# [[ 9 25  4]\n",
    "#  [ 8 24 16]\n",
    "#  [17 11 21]\n",
    "#  [ 3 22  3]\n",
    "#  [ 3 15  3]\n",
    "#  [18 17 25]\n",
    "#  [16  5 12]\n",
    "#  [29 27 17]]\n",
    "\n",
    "y = np.argsort(x, axis=0)\n",
    "print(y)\n",
    "# [[3 6 3]\n",
    "#  [4 2 4]\n",
    "#  [1 4 0]\n",
    "#  [0 5 6]\n",
    "#  [6 3 1]\n",
    "#  [2 1 7]\n",
    "#  [5 0 2]\n",
    "#  [7 7 5]]\n",
    "\n",
    "z = np.argpartition(x, kth=2, axis=0)\n",
    "print(z)\n",
    "# [[3 6 3]\n",
    "#  [4 2 4]\n",
    "#  [1 4 0]\n",
    "#  [0 3 2]\n",
    "#  [2 1 1]\n",
    "#  [5 5 5]\n",
    "#  [6 0 6]\n",
    "#  [7 7 7]]\n",
    "```\n",
    "\n",
    "【例】选取每一列第三小的数的索引\n",
    "\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(100)\n",
    "x = np.random.randint(1, 30, [8, 3])\n",
    "print(x)\n",
    "# [[ 9 25  4]\n",
    "#  [ 8 24 16]\n",
    "#  [17 11 21]\n",
    "#  [ 3 22  3]\n",
    "#  [ 3 15  3]\n",
    "#  [18 17 25]\n",
    "#  [16  5 12]\n",
    "#  [29 27 17]]\n",
    "\n",
    "z = np.argpartition(x, kth=2, axis=0)\n",
    "print(z[2])\n",
    "# [1 4 0]\n",
    "```\n",
    "\n",
    "【例】选取每一列第三大的数的索引\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(100)\n",
    "x = np.random.randint(1, 30, [8, 3])\n",
    "print(x)\n",
    "# [[ 9 25  4]\n",
    "#  [ 8 24 16]\n",
    "#  [17 11 21]\n",
    "#  [ 3 22  3]\n",
    "#  [ 3 15  3]\n",
    "#  [18 17 25]\n",
    "#  [16  5 12]\n",
    "#  [29 27 17]]\n",
    "\n",
    "z = np.argpartition(x, kth=-3, axis=0)\n",
    "print(z[-3])\n",
    "# [2 1 7]\n",
    "```\n",
    "\n",
    "\n",
    "---\n",
    "## 搜索\n",
    "### numpy.argmax()\n",
    "- `numpy.argmax(a[, axis=None, out=None])`Returns the indices of the maximum values along an axis.\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(20200612)\n",
    "x = np.random.rand(5, 5) * 10\n",
    "x = np.around(x, 2)\n",
    "print(x)\n",
    "# [[2.32 7.54 9.78 1.73 6.22]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [0.01 4.23 0.19 1.73 9.27]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [9.05 0.07 8.95 7.9  6.99]]\n",
    "\n",
    "y = np.argmax(x)\n",
    "print(y)  # 2\n",
    "\n",
    "y = np.argmax(x, axis=0)\n",
    "print(y)\n",
    "# [4 0 0 1 2]\n",
    "\n",
    "y = np.argmax(x, axis=1)\n",
    "print(y)\n",
    "# [2 3 4 0 0]\n",
    "```\n",
    "### numpy.argmin()\n",
    "- `numpy.argmin(a[, axis=None, out=None])`Returns the indices of the minimum values along an axis.\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(20200612)\n",
    "x = np.random.rand(5, 5) * 10\n",
    "x = np.around(x, 2)\n",
    "print(x)\n",
    "# [[2.32 7.54 9.78 1.73 6.22]\n",
    "#  [6.93 5.17 9.28 9.76 8.25]\n",
    "#  [0.01 4.23 0.19 1.73 9.27]\n",
    "#  [7.99 4.97 0.88 7.32 4.29]\n",
    "#  [9.05 0.07 8.95 7.9  6.99]]\n",
    "\n",
    "y = np.argmin(x)\n",
    "print(y)  # 10\n",
    "\n",
    "y = np.argmin(x, axis=0)\n",
    "print(y)\n",
    "# [2 4 2 0 3]\n",
    "\n",
    "y = np.argmin(x, axis=1)\n",
    "print(y)\n",
    "# [3 1 0 2 1]\n",
    "```\n",
    "### numppy.nonzero()\n",
    "\n",
    "- `numppy.nonzero(a)` Return the indices of the elements that are non-zero.\n",
    "\n",
    "，其值为非零元素的下标在对应轴上的值。\n",
    "\n",
    "1. 只有`a`中非零元素才会有索引值，那些零值元素没有索引值。\n",
    "2. 返回一个长度为`a.ndim`的元组（tuple），元组的每个元素都是一个整数数组（array）。\n",
    "3. 每一个array均是从一个维度上来描述其索引值。比如，如果`a`是一个二维数组，则tuple包含两个array，第一个array从行维度来描述索引值；第二个array从列维度来描述索引值。\n",
    "4. 该 `np.transpose(np.nonzero(x))` 函数能够描述出每一个非零元素在不同维度的索引值。\n",
    "5. 通过`a[nonzero(a)]`得到所有`a`中的非零值。\n",
    "\n",
    "【例】一维数组\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([0, 2, 3])\n",
    "print(x)  # [0 2 3]\n",
    "print(x.shape)  # (3,)\n",
    "print(x.ndim)  # 1\n",
    "\n",
    "y = np.nonzero(x)\n",
    "print(y)  # (array([1, 2], dtype=int64),)\n",
    "print(np.array(y))  # [[1 2]]\n",
    "print(np.array(y).shape)  # (1, 2)\n",
    "print(np.array(y).ndim)  # 2\n",
    "print(np.transpose(y))\n",
    "# [[1]\n",
    "#  [2]]\n",
    "print(x[np.nonzero(x)])\n",
    "#[2, 3]\n",
    "```\n",
    "\n",
    "【例】二维数组\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[3, 0, 0], [0, 4, 0], [5, 6, 0]])\n",
    "print(x)\n",
    "# [[3 0 0]\n",
    "#  [0 4 0]\n",
    "#  [5 6 0]]\n",
    "print(x.shape)  # (3, 3)\n",
    "print(x.ndim)  # 2\n",
    "\n",
    "y = np.nonzero(x)\n",
    "print(y)\n",
    "# (array([0, 1, 2, 2], dtype=int64), array([0, 1, 0, 1], dtype=int64))\n",
    "print(np.array(y))\n",
    "# [[0 1 2 2]\n",
    "#  [0 1 0 1]]\n",
    "print(np.array(y).shape)  # (2, 4)\n",
    "print(np.array(y).ndim)  # 2\n",
    "\n",
    "y = x[np.nonzero(x)]\n",
    "print(y)  # [3 4 5 6]\n",
    "\n",
    "y = np.transpose(np.nonzero(x))\n",
    "print(y)\n",
    "# [[0 0]\n",
    "#  [1 1]\n",
    "#  [2 0]\n",
    "#  [2 1]]\n",
    "```\n",
    "【例】三维数组\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[[0, 1], [1, 0]], [[0, 1], [1, 0]], [[0, 0], [1, 0]]])\n",
    "print(x)\n",
    "# [[[0 1]\n",
    "#   [1 0]]\n",
    "#\n",
    "#  [[0 1]\n",
    "#   [1 0]]\n",
    "#\n",
    "#  [[0 0]\n",
    "#   [1 0]]]\n",
    "print(np.shape(x))  # (3, 2, 2)\n",
    "print(x.ndim)  # 3\n",
    "\n",
    "y = np.nonzero(x)\n",
    "print(np.array(y))\n",
    "# [[0 0 1 1 2]\n",
    "#  [0 1 0 1 1]\n",
    "#  [1 0 1 0 0]]\n",
    "print(np.array(y).shape)  # (3, 5)\n",
    "print(np.array(y).ndim)  # 2\n",
    "print(y)\n",
    "# (array([0, 0, 1, 1, 2], dtype=int64), array([0, 1, 0, 1, 1], dtype=int64), array([1, 0, 1, 0, 0], dtype=int64))\n",
    "print(x[np.nonzero(x)])\n",
    "#[1 1 1 1 1]\n",
    "```\n",
    "\n",
    "【例】`nonzero()`将布尔数组转换成整数数组进行操作。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])\n",
    "print(x)\n",
    "# [[1 2 3]\n",
    "#  [4 5 6]\n",
    "#  [7 8 9]]\n",
    "\n",
    "y = x > 3\n",
    "print(y)\n",
    "# [[False False False]\n",
    "#  [ True  True  True]\n",
    "#  [ True  True  True]]\n",
    "\n",
    "y = np.nonzero(x > 3)\n",
    "print(y)\n",
    "# (array([1, 1, 1, 2, 2, 2], dtype=int64), array([0, 1, 2, 0, 1, 2], dtype=int64))\n",
    "\n",
    "y = x[np.nonzero(x > 3)]\n",
    "print(y)\n",
    "# [4 5 6 7 8 9]\n",
    "\n",
    "y = x[x > 3]\n",
    "print(y)\n",
    "# [4 5 6 7 8 9]\n",
    "```\n",
    "### numpy.where()\n",
    "- `numpy.where(condition, [x=None, y=None])`  Return elements chosen from `x` or `y` depending on `condition`.\n",
    "\n",
    "【例】满足条件`condition`，输出`x`，不满足输出`y`。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.arange(10)\n",
    "print(x)\n",
    "# [0 1 2 3 4 5 6 7 8 9]\n",
    "\n",
    "y = np.where(x < 5, x, 10 * x)\n",
    "print(y)\n",
    "# [ 0  1  2  3  4 50 60 70 80 90]\n",
    "\n",
    "x = np.array([[0, 1, 2],\n",
    "              [0, 2, 4],\n",
    "              [0, 3, 6]])\n",
    "y = np.where(x < 4, x, -1)\n",
    "print(y)\n",
    "# [[ 0  1  2]\n",
    "#  [ 0  2 -1]\n",
    "#  [ 0  3 -1]]\n",
    "```\n",
    "\n",
    "【例】只有`condition`，没有`x`和`y`，则输出满足条件 (即非0) 元素的坐标 (等价于`numpy.nonzero`)。这里的坐标以tuple的形式给出，通常原数组有多少维，输出的tuple中就包含几个数组，分别对应符合条件元素的各维坐标。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([1, 2, 3, 4, 5, 6, 7, 8])\n",
    "y = np.where(x > 5)\n",
    "print(y)\n",
    "# (array([5, 6, 7], dtype=int64),)\n",
    "print(x[y])\n",
    "# [6 7 8]\n",
    "\n",
    "y = np.nonzero(x > 5)\n",
    "print(y)\n",
    "# (array([5, 6, 7], dtype=int64),)\n",
    "print(x[y])\n",
    "# [6 7 8]\n",
    "\n",
    "x = np.array([[11, 12, 13, 14, 15],\n",
    "              [16, 17, 18, 19, 20],\n",
    "              [21, 22, 23, 24, 25],\n",
    "              [26, 27, 28, 29, 30],\n",
    "              [31, 32, 33, 34, 35]])\n",
    "y = np.where(x > 25)\n",
    "print(y)\n",
    "# (array([3, 3, 3, 3, 3, 4, 4, 4, 4, 4], dtype=int64), array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], dtype=int64))\n",
    "\n",
    "print(x[y])\n",
    "# [26 27 28 29 30 31 32 33 34 35]\n",
    "\n",
    "y = np.nonzero(x > 25)\n",
    "print(y)\n",
    "# (array([3, 3, 3, 3, 3, 4, 4, 4, 4, 4], dtype=int64), array([0, 1, 2, 3, 4, 0, 1, 2, 3, 4], dtype=int64))\n",
    "print(x[y])\n",
    "# [26 27 28 29 30 31 32 33 34 35]\n",
    "```\n",
    "\n",
    "\n",
    "\n",
    "### numpy.searchsorted()\n",
    "- `numpy.searchsorted(a, v[, side='left', sorter=None])` Find indices where elements should be inserted to maintain order.\n",
    "    - a：一维输入数组。当`sorter`参数为`None`的时候，`a`必须为升序数组；否则，`sorter`不能为空，存放`a`中元素的`index`，用于反映`a`数组的升序排列方式。\n",
    "    - v：插入`a`数组的值，可以为单个元素，`list`或者`ndarray`。\n",
    "    - side：查询方向，当为`left`时，将返回第一个符合条件的元素下标；当为`right`时，将返回最后一个符合条件的元素下标。\n",
    "    - sorter：一维数组存放`a`数组元素的 index，index 对应元素为升序。\n",
    "\n",
    "\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([0, 1, 5, 9, 11, 18, 26, 33])\n",
    "y = np.searchsorted(x, 15)\n",
    "print(y)  # 5\n",
    "\n",
    "y = np.searchsorted(x, 15, side='right')\n",
    "print(y)  # 5\n",
    "\n",
    "y = np.searchsorted(x, -1)\n",
    "print(y)  # 0\n",
    "\n",
    "y = np.searchsorted(x, -1, side='right')\n",
    "print(y)  # 0\n",
    "\n",
    "y = np.searchsorted(x, 35)\n",
    "print(y)  # 8\n",
    "\n",
    "y = np.searchsorted(x, 35, side='right')\n",
    "print(y)  # 8\n",
    "\n",
    "y = np.searchsorted(x, 11)\n",
    "print(y)  # 4\n",
    "\n",
    "y = np.searchsorted(x, 11, side='right')\n",
    "print(y)  # 5\n",
    "\n",
    "y = np.searchsorted(x, 0)\n",
    "print(y)  # 0\n",
    "\n",
    "y = np.searchsorted(x, 0, side='right')\n",
    "print(y)  # 1\n",
    "\n",
    "y = np.searchsorted(x, 33)\n",
    "print(y)  # 7\n",
    "\n",
    "y = np.searchsorted(x, 33, side='right')\n",
    "print(y)  # 8\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([0, 1, 5, 9, 11, 18, 26, 33])\n",
    "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35])\n",
    "print(y)  # [0 0 4 5 7 8]\n",
    "\n",
    "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35], side='right')\n",
    "print(y)  # [0 1 5 5 8 8]\n",
    "```\n",
    "\n",
    "【例】\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.array([0, 1, 5, 9, 11, 18, 26, 33])\n",
    "np.random.shuffle(x)\n",
    "print(x)  # [33  1  9 18 11 26  0  5]\n",
    "\n",
    "x_sort = np.argsort(x)\n",
    "print(x_sort)  # [6 1 7 2 4 3 5 0]\n",
    "\n",
    "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35], sorter=x_sort)\n",
    "print(y)  # [0 0 4 5 7 8]\n",
    "\n",
    "y = np.searchsorted(x, [-1, 0, 11, 15, 33, 35], side='right', sorter=x_sort)\n",
    "print(y)  # [0 1 5 5 8 8]\n",
    "```\n",
    "\n",
    "\n",
    "---\n",
    "## 计数\n",
    "### numpy.count_nonzero()\n",
    "- `numpy.count_nonzero(a, axis=None)` Counts the number of non-zero values in the array a.\n",
    "\n",
    "【例】返回数组中的非0元素个数。\n",
    "```python\n",
    "import numpy as np\n",
    "\n",
    "x = np.count_nonzero(np.eye(4))\n",
    "print(x)  # 4\n",
    "\n",
    "x = np.count_nonzero([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]])\n",
    "print(x)  # 5\n",
    "\n",
    "x = np.count_nonzero([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]], axis=0)\n",
    "print(x)  # [1 1 1 1 1]\n",
    "\n",
    "x = np.count_nonzero([[0, 1, 7, 0, 0], [3, 0, 0, 2, 19]], axis=1)\n",
    "print(x)  # [2 3]\n",
    "```\n",
    "\n",
    "---\n",
    "**参考文献**\n",
    "\n",
    "- https://blog.csdn.net/u013698770/article/details/54632047\n",
    "- https://www.cnblogs.com/massquantity/p/8908859.html\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python35",
   "language": "python",
   "name": "python35"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.10"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
